from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from sqlalchemy import or_
from app.api.deps import get_db
from app.models.product.product_category import ProductCategory
from app.schemas.product import ProductCategoryCreate, ProductCategoryUpdate
from app.utils.response import success, success_pagination, success_action, not_found, bad_request

router = APIRouter()


@router.post("/", summary="创建商品分类")
def create_category(
    category: ProductCategoryCreate,
    db: Session = Depends(get_db)
):
    """
    创建新的商品分类

    - **name**: 分类名称（必填）
    - **description**: 分类描述（可选）
    - **parent_id**: 父分类ID（可选，支持层级分类）
    - **sort_order**: 排序顺序（默认为0）
    - **is_active**: 是否激活（1-激活，0-禁用，默认为1）
    """
    # 检查分类名称是否已存在
    existing_category = db.query(ProductCategory).filter(
        ProductCategory.name == category.name
    ).first()
    if existing_category:
        return bad_request(message="分类名称已存在")

    # 如果指定了父分类，检查父分类是否存在
    if category.parent_id:
        parent_category = db.query(ProductCategory).filter(
            ProductCategory.id == category.parent_id
        ).first()
        if not parent_category:
            return not_found(message="父分类不存在")

    db_category = ProductCategory(**category.model_dump())
    db.add(db_category)
    db.commit()
    db.refresh(db_category)
    return success(data=db_category, message="分类创建成功")


@router.get("/", summary="获取商品分类列表")
def get_categories(
    page_no: int = Query(1, ge=1, description="页码（从1开始）"),
    page_size: int = Query(20, ge=1, le=1000, description="每页记录数"),
    parent_id: int = Query(None, description="筛选指定父分类下的子分类"),
    is_active: int = Query(None, ge=0, le=1, description="筛选激活状态"),
    search: str = Query(None, description="搜索分类名称或描述"),
    db: Session = Depends(get_db)
):
    """
    获取商品分类列表，支持分页和筛选

    - **page_no**: 页码（从1开始）
    - **page_size**: 每页记录数
    - **parent_id**: 筛选指定父分类下的子分类
    - **is_active**: 筛选激活状态（1-激活，0-禁用）
    - **search**: 搜索分类名称或描述
    """
    query = db.query(ProductCategory)

    # 筛选条件
    if parent_id is not None:
        query = query.filter(ProductCategory.parent_id == parent_id)

    if is_active is not None:
        query = query.filter(ProductCategory.is_active == is_active)

    if search:
        query = query.filter(
            or_(
                ProductCategory.name.contains(search),
                ProductCategory.description.contains(search)
            )
        )

    # 按排序顺序和ID排序
    query = query.order_by(ProductCategory.sort_order.asc(), ProductCategory.id.asc())

    # 获取总数
    total = query.count()

    # 计算分页参数
    skip = (page_no - 1) * page_size

    categories = query.offset(skip).limit(page_size).all()
    return success_pagination(
        data=categories,
        total=total,
        page_no=page_no,
        page_size=page_size,
        message="获取分类列表成功"
    )


@router.get("/{category_id}", summary="获取单个商品分类")
def get_category(
    category_id: int,
    db: Session = Depends(get_db)
):
    """
    根据ID获取单个商品分类详情

    - **category_id**: 分类ID
    """
    category = db.query(ProductCategory).filter(ProductCategory.id == category_id).first()
    if not category:
        return not_found(message="分类不存在")
    return success(data=category, message="获取分类详情成功")


@router.put("/{category_id}", summary="更新商品分类")
def update_category(
    category_id: int,
    category_update: ProductCategoryUpdate,
    db: Session = Depends(get_db)
):
    """
    更新商品分类信息

    - **category_id**: 分类ID
    - **name**: 分类名称（可选）
    - **description**: 分类描述（可选）
    - **parent_id**: 父分类ID（可选）
    - **sort_order**: 排序顺序（可选）
    - **is_active**: 是否激活（可选）
    """
    db_category = db.query(ProductCategory).filter(ProductCategory.id == category_id).first()
    if not db_category:
        return not_found(message="分类不存在")

    # 检查新的分类名称是否已存在（除了当前分类）
    if category_update.name and category_update.name != db_category.name:
        existing_category = db.query(ProductCategory).filter(
            ProductCategory.name == category_update.name,
            ProductCategory.id != category_id
        ).first()
        if existing_category:
            return bad_request(message="分类名称已存在")

    # 如果更新了父分类，检查父分类是否存在且不能是自己
    if category_update.parent_id is not None:
        if category_update.parent_id == category_id:
            return bad_request(message="不能将自己设为父分类")

        parent_category = db.query(ProductCategory).filter(
            ProductCategory.id == category_update.parent_id
        ).first()
        if not parent_category:
            return not_found(message="父分类不存在")

    # 更新字段
    update_data = category_update.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(db_category, field, value)

    db.commit()
    db.refresh(db_category)
    return success(data=db_category, message="分类更新成功")


@router.delete("/{category_id}", summary="删除商品分类")
def delete_category(
    category_id: int,
    force: bool = Query(False, description="强制删除（包括子分类）"),
    db: Session = Depends(get_db)
):
    """
    删除商品分类

    - **category_id**: 分类ID
    - **force**: 是否强制删除（包括子分类）
    """
    db_category = db.query(ProductCategory).filter(ProductCategory.id == category_id).first()
    if not db_category:
        return not_found(message="分类不存在")

    # 检查是否有子分类
    children_count = db.query(ProductCategory).filter(
        ProductCategory.parent_id == category_id
    ).count()

    if children_count > 0 and not force:
        return bad_request(message=f"该分类下有 {children_count} 个子分类，请先删除子分类或使用强制删除")

    # 强制删除时，先删除所有子分类
    if force and children_count > 0:
        children = db.query(ProductCategory).filter(
            ProductCategory.parent_id == category_id
        ).all()
        for child in children:
            db.delete(child)

    # 删除分类
    db.delete(db_category)
    db.commit()

    return success_action(message="分类删除成功")


@router.get("/{category_id}/children", summary="获取子分类列表")
def get_category_children(
    category_id: int,
    db: Session = Depends(get_db)
):
    """
    获取指定分类的所有子分类

    - **category_id**: 父分类ID
    """
    parent_category = db.query(ProductCategory).filter(ProductCategory.id == category_id).first()
    if not parent_category:
        return not_found(message="分类不存在")

    children = db.query(ProductCategory).filter(
        ProductCategory.parent_id == category_id
    ).order_by(ProductCategory.sort_order.asc(), ProductCategory.id.asc()).all()

    return success(data=children, message="获取子分类成功")


@router.get("/tree/", summary="获取分类树")
def get_category_tree(
    is_active: int = Query(None, ge=0, le=1, description="筛选激活状态"),
    db: Session = Depends(get_db)
):
    """
    获取完整的分类树结构

    - **is_active**: 筛选激活状态（1-激活，0-禁用，不指定则返回所有）
    """
    query = db.query(ProductCategory).filter(ProductCategory.parent_id.is_(None))

    if is_active is not None:
        query = query.filter(ProductCategory.is_active == is_active)

    root_categories = query.order_by(ProductCategory.sort_order.asc(), ProductCategory.id.asc()).all()

    def build_tree(categories):
        result = []
        for category in categories:
            # 将 SQLAlchemy 对象转换为字典
            category_dict = {
                'id': category.id,
                'name': category.name,
                'description': category.description,
                'parent_id': category.parent_id,
                'sort_order': category.sort_order,
                'is_active': category.is_active,
                'created_at': category.created_at.isoformat() if category.created_at else None,
                'updated_at': category.updated_at.isoformat() if category.updated_at else None
            }

            # 查找子分类
            children_query = db.query(ProductCategory).filter(
                ProductCategory.parent_id == category.id
            )
            if is_active is not None:
                children_query = children_query.filter(ProductCategory.is_active == is_active)

            children = children_query.order_by(
                ProductCategory.sort_order.asc(),
                ProductCategory.id.asc()
            ).all()

            if children:
                category_dict['children'] = build_tree(children)

            result.append(category_dict)

        return result

    return success(data=build_tree(root_categories), message="获取分类树成功")